/*
 * Copyright (C) 2007 Evan Long    longx223 (at) umn (dot) edu
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/**
 * @file   gesture_recognition.h
 * @author Evan Long
 * 
 * @brief  Definition of code to recognize a gesture given a series of points.
 * 
 * 
 */

#ifndef GESTURE_RECOGNITION_H
#define GESTURE_RECOGNITION_H

#include "image_proc.h"
#include "cvector.h"

/**
 * Minimum between two adjacent points before a slope and direction can be 
 * calculated.
 */
#define POINT_DIST 10

/**
 * Amount of space to allocate for a string that represents the recognized 
 * gesture. 4 characters for the command and 1 for NUL. 
 */
#define CMD_SIZE 5

/**
 * Every zone is considered HORIZONTAL except for the zone that is VERTICAL. 
 * The vertical zone is zone zero. 
 */
#define VERTICAL   1
#define HORIZONTAL 2


#define MIN(A,B) (A < B) ? A : B

#define PI 3.14159

/**
 * Keeps track of information for a specific zone. 
 * 
 * @param total_points Number of data points that were found in a zone.
 * @param order Sum of indexes of the various data points. Can be used to 
 * figure out which zone came first. 
 * @param up Track direction points are going in a zone.
 * @param down Track direction points are going in a zone.
 * @param left Track direction points are going in a zone.
 * @param right Track direction points are going in a zone.
 */
typedef struct zone
{
  int total_points;
  int order;
  int up;
  int down;
  int left;
  int right;
} zone_t;

/** 
 * Given a zone a character is returned which represents the direction that was
 * common in that zone. 
 * 
 * @param z Instance of a zone.
 * 
 * @return Either a 'u' for up, 'd' for down, 'l' for left, or 'r' for right. 
 */
char get_dir(zone_t* z);

/** 
 * Given a zone and two points the correct direction is determined based on
 * the value of dir. If dir is VERTICAL then the possible direction for zone
 * is UP or DOWN. If dir is HORIZONTAL then the possbilities are LEFT and 
 * RIGHT.
 * 
 * @param z Instance of a zone.
 * @param p1 First point.
 * @param p2 Second point.
 * @param dir Direction either HORIZONTAL or VERTICAL.
 */
void pick_dir(zone_t* z, point_t* p1, point_t* p2, int dir);

/** 
 * The monitor loop collects a sequential set of points and detect_gesture
 * breaks those points apart into zones such that some sort of gesture can be
 * derived from it. The algorithm to do this is very simple and is by no means
 * any sort of advanced algorithm. It does get the job done though. The 
 * limitations of it are that it is limited to only one or two zones for a 
 * gesture. For the purposes of controling VLC this is more than enough. User
 * will need to free the command that this function allocates.
 *
 * A gesture command string has the following format:
 * 4 character sequence where the first and third characters represent a zone
 * and the second and forth represent their respective directions. If the 
 * gesture is only in one zone then the third and forth charaters are filled 
 * with the character '9'. 
 *
 * There are four zones: vertical, horizontal, positive sloping, and negative
 * sloping zones. The vertical and horizontal zones are each 30 degrees wide 
 * and the remaining zones are each 60 degrees wide. 
 * 
 * @param points Set of data points that are collected my monitor loop
 * 
 * @return String that is associated with a gesture. Needs to be freed
 * by the user. 
 */
char* detect_gesture(cvector_t* points);

#endif
